package com.lotso.web.common.security;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lotso.web.common.exception.BusinessException;
import com.lotso.web.module.system.entity.Menu;
import com.lotso.web.module.system.entity.User;
import com.lotso.web.module.system.service.impl.MenuServiceImpl;
import com.lotso.web.module.system.service.impl.UserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * ClassName: CumDetailsService
 * Description: 自定义用户认证授权实现 UserDetailsService
 * 在这个类中，可以从数据库中读入用户的密码，角色信息，是否锁定，账号是否过期等
 * Date: 2017/12/27 15:36 【需求编号】
 *
 * @author Shaom
 * @version V1.0.0
 */
@Slf4j
@Component
public class CustomDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private MenuServiceImpl menuService;

    /**
     * 只有登录的时候会调用，需要更新权限数据
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.debug("登录用户名： {}", username);
        User user = userService.getByUsername(username);
        if (Objects.isNull(user)) {
            throw new BusinessException("不存在的用户");
        }

        // 菜单显示
        List<Menu> authorities = menuService.listByUserId(user.getId());
        List<Map<String, Object>> menuTree = this.getMenuTree(authorities, Menu.ROOT_ID);
        this.getSession().setAttribute("menus", menuTree);

        // 授权
        List<GrantedAuthority> grantedAuthorities = Lists.newArrayList();
        for (Menu authority : authorities) {
            if (!Strings.isNullOrEmpty(authority.getAuthority())) {
                grantedAuthorities.add(new SimpleGrantedAuthority(authority.getAuthority()));
            }
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities);
    }

    /**
     * 递归转化树形菜单
     */
    private List<Map<String, Object>> getMenuTree(List<Menu> authorities, String parentId) {
        List<Map<String, Object>> list = new ArrayList<>();

        for (Menu temp : authorities) {
            if (temp.getIsMenu() == 0 && Objects.equals(parentId, temp.getParentId())) {
                Map<String, Object> map = Maps.newHashMap();
                map.put("menuName", temp.getMenuName());
                map.put("menuIcon", temp.getMenuIcon());
                map.put("menuUrl", Strings.isNullOrEmpty(temp.getMenuUrl()) ? "javascript:;" : temp.getMenuUrl());
                map.put("subMenus", this.getMenuTree(authorities, temp.getId()));
                list.add(map);
            }
        }
        return list;
    }

    private HttpSession getSession() {
        ServletRequestAttributes attr = (ServletRequestAttributes)
                RequestContextHolder.currentRequestAttributes();
        return attr.getRequest().getSession(true);
    }


}
